Skip to content

Instantly share code, notes, and snippets.

@EncodeTheCode
Created May 20, 2024 02:11
Show Gist options
  • Save EncodeTheCode/b866d8f3dfdb0b497d92c3e33d1c4b55 to your computer and use it in GitHub Desktop.
Save EncodeTheCode/b866d8f3dfdb0b497d92c3e33d1c4b55 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Custom Scrollbar Windows 95 Style</title>
<style>
body {
margin: 0;
font-family: Arial, sans-serif;
background-color: #c3c3c3;
}
.scroll-container {
position: relative;
width: 300px;
height: 200px;
border: 2px solid #808080;
background-color: #ffffff;
overflow: hidden; /* Hide default scrollbars */
}
.scroll-content {
width: 1000px; /* Large width to ensure horizontal scrollbar */
height: 400px; /* Large height to ensure vertical scrollbar */
padding: 10px;
box-sizing: border-box;
overflow: hidden; /* Hide default scrollbars */
position: relative;
}
.scrollbar {
position: absolute;
background: #c3c3c3;
z-index: 10;
}
.scrollbar.vertical {
width: 16px;
top: 0;
right: 0;
bottom: 16px; /* Adjust to leave space for the bottom scrollbar */
}
.scrollbar.horizontal {
height: 16px;
left: 0;
right: 16px; /* Adjust to leave space for the right scrollbar */
bottom: 0;
}
.thumb {
background: #808080;
position: absolute;
cursor: pointer;
box-shadow: inset 1px 1px 0px #fff, inset -1px -1px 0px #000;
}
.scrollbar.vertical .thumb {
width: 100%;
}
.scrollbar.horizontal .thumb {
height: 100%;
}
.scroll-container > div:nth-child(2) > div:nth-child(1){
background: linear-gradient(90deg, transparent 12%, rgba(107,107,107,0.5) 15%, rgba(106,106,106,0) 96%, rgba(2,0,36,1) 97%);
border:1px solid #8C8C8C;
-webkit-box-shadow: 0px 0px 1px 1px rgba(0,0,0,0.55);
-moz-box-shadow: 0px 0px 1px 1px rgba(0,0,0,0.55);
box-shadow: 0px 0px 1px 1px rgba(0,0,0,0.55);
}
.scroll-container > div:nth-child(3) > div:nth-child(1){
background: linear-gradient(0deg, transparent 12%, rgba(107,107,107,0.5) 15%, rgba(106,106,106,0) 96%, rgba(2,0,36,1) 97%);
border:1px solid #8C8C8C;
-webkit-box-shadow: 0px 0px 1px 1px rgba(0,0,0,0.55);
-moz-box-shadow: 0px 0px 1px 1px rgba(0,0,0,0.55);
box-shadow: 0px 0px 1px 1px rgba(0,0,0,0.55);
}
.scroll-container > div:nth-child(2){
-webkit-box-shadow: 0px 0px 1px 1px rgba(0,0,0,0.55);
-moz-box-shadow: 0px 0px 1px 1px rgba(0,0,0,0.55);
box-shadow: 0px 0px 1px 1px rgba(0,0,0,0.55);
}
</style>
</head>
<body>
<div class="scroll-container">
<div class="scroll-content" contenteditable="true">
<!-- Editable content inside the scrollable div -->
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent bibendum blandit erat. Proin ut fermentum nulla. In hac habitasse platea dictumst. Morbi ac tortor at lacus tempus aliquam a non nulla. Integer a semper risus. Nulla facilisi. Vivamus at eros a urna varius consequat et id nunc. Phasellus imperdiet, odio at sollicitudin vehicula, ligula metus commodo neque, ut cursus lacus odio id nisi. Mauris imperdiet turpis nec felis gravida, nec dapibus orci aliquet. Suspendisse potenti. Integer non venenatis erat.</p>
<p>Ut congue, justo non mollis iaculis, purus lorem hendrerit quam, nec malesuada ex ligula eget odio. Suspendisse euismod augue et facilisis gravida. Nunc vel dui et velit cursus interdum. Nulla aliquet nisl eu justo dictum, sit amet tristique leo finibus. Morbi rutrum, justo nec scelerisque dapibus, nulla lacus facilisis ligula, eu tincidunt justo est eget ligula. Integer consectetur, arcu in fermentum laoreet, orci odio iaculis risus, eget porttitor eros nisl at libero. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Integer id odio sem. Aenean imperdiet purus in urna bibendum, non vulputate risus sagittis. Vivamus at pharetra justo.</p>
<p>Additional content to ensure horizontal scrolling. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent bibendum blandit erat. Proin ut fermentum nulla. In hac habitasse platea dictumst. Morbi ac tortor at lacus tempus aliquam a non nulla. Integer a semper risus. Nulla facilisi. Vivamus at eros a urna varius consequat et id nunc. Phasellus imperdiet, odio at sollicitudin vehicula, ligula metus commodo neque, ut cursus lacus odio id nisi. Mauris imperdiet turpis nec felis gravida, nec dapibus orci aliquet. Suspendisse potenti. Integer non venenatis erat.</p>
<p>Ut congue, justo non mollis iaculis, purus lorem hendrerit quam, nec malesuada ex ligula eget odio. Suspendisse euismod augue et facilisis gravida. Nunc vel dui et velit cursus interdum. Nulla aliquet nisl eu justo dictum, sit amet tristique leo finibus. Morbi rutrum, justo nec scelerisque dapibus, nulla lacus facilisis ligula, eu tincidunt justo est eget ligula. Integer consectetur, arcu in fermentum laoreet, orci odio iaculis risus, eget porttitor eros nisl at libero. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Integer id odio sem. Aenean imperdiet purus in urna bibendum, non vulputate risus sagittis. Vivamus at pharetra justo.</p>
<p>Additional content to ensure horizontal scrolling. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent bibendum blandit erat. Proin ut fermentum nulla. In hac habitasse platea dictumst. Morbi ac tortor at lacus tempus aliquam a non nulla. Integer a semper risus. Nulla facilisi. Vivamus at eros a urna varius consequat et id nunc. Phasellus imperdiet, odio at sollicitudin vehicula, ligula metus commodo neque, ut cursus lacus odio id nisi. Mauris imperdiet turpis nec felis gravida, nec dapibus orci aliquet. Suspendisse potenti. Integer non venenatis erat.</p>
<p>Ut congue, justo non mollis iaculis, purus lorem hendrerit quam, nec malesuada ex ligula eget odio. Suspendisse euismod augue et facilisis gravida. Nunc vel dui et velit cursus interdum. Nulla aliquet nisl eu justo dictum, sit amet tristique leo finibus. Morbi rutrum, justo nec scelerisque dapibus, nulla lacus facilisis ligula, eu tincidunt justo est eget ligula. Integer consectetur, arcu in fermentum laoreet, orci odio iaculis risus, eget porttitor eros nisl at libero. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Integer id odio sem. Aenean imperdiet purus in urna bibendum, non vulputate risus sagittis. Vivamus at pharetra justo.</p>
<p>Additional content to ensure horizontal scrolling. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.</p>
</div>
<div class="scrollbar vertical">
<div class="thumb"></div>
</div>
<div class="scrollbar horizontal">
<div class="thumb"></div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const container = document.querySelector('.scroll-container');
const content = document.querySelector('.scroll-content');
const verticalScrollbar = document.querySelector('.scrollbar.vertical');
const horizontalScrollbar = document.querySelector('.scrollbar.horizontal');
const verticalThumb = verticalScrollbar.querySelector('.thumb');
const horizontalThumb = horizontalScrollbar.querySelector('.thumb');
let scrollbarCreated = true; // Move the flag outside the function to retain its state
function updateScrollbars() {
const containerHeight = container.clientHeight;
const contentHeight = content.scrollHeight;
const containerWidth = container.clientWidth;
const contentWidth = content.scrollWidth;
const verticalThumbHeight = Math.max(containerHeight * (containerHeight / contentHeight), 20);
verticalThumb.style.height = `${verticalThumbHeight}px`;
const horizontalThumbWidth = Math.max(containerWidth * (containerWidth / contentWidth), 20);
horizontalThumb.style.width = `${horizontalThumbWidth}px`;
const verticalRatio = content.scrollTop / (contentHeight - containerHeight);
const horizontalRatio = content.scrollLeft / (contentWidth - containerWidth);
if (scrollbarCreated) {
verticalThumb.style.top = `${verticalRatio * (containerHeight - verticalThumbHeight)}px`;
horizontalThumb.style.left = `${horizontalRatio * (containerWidth - horizontalThumbWidth)}px`;
verticalThumb.style.marginTop = '18px';
verticalThumb.style.marginBottom = '18px';
horizontalThumb.style.marginRight = '18px';
horizontalThumb.style.marginLeft = '18px';
scrollbarCreated = false; // Set the flag to false after the initial update
function updateMarginLeft(element, expectedValue, newValue) {
// Get the computed style of the element
const computedStyle = window.getComputedStyle(element);
const marginLeft = computedStyle.marginLeft;
// Compare the marginLeft with the expected value
if (marginLeft !== expectedValue) {
// Set the new value if it is different
element.style.marginLeft = newValue;
}
}
updateMarginLeft(horizontalThumb, '18px', '18px');
setTimeout(() => {
verticalThumb.style.top = `${verticalRatio * (containerHeight - verticalThumbHeight)}px`;
horizontalThumb.style.left = `${horizontalRatio * (containerWidth - horizontalThumbWidth)}px`;
verticalThumb.style.marginTop = '0px';
verticalThumb.style.marginBottom = '0px';
horizontalThumb.style.marginRight = '0px';
horizontalThumb.style.marginLeft = '0px';
verticalThumb.style.top = `${verticalRatio * (containerHeight - verticalThumbHeight)+18}px`;
horizontalThumb.style.left = `${horizontalRatio * (containerWidth - horizontalThumbWidth)+18}px`;
updateMarginLeft(horizontalThumb, '0px', '18px');
}, 125); // Use setTimeout to ensure this runs after the initial update
setTimeout(() => {
updateMarginLeft(horizontalThumb, '-18px', '0px');
}, 525);
setTimeout(() => {
horizontalThumb.style.left = `${horizontalRatio * (containerWidth - horizontalThumbWidth)+18}px`;
updateMarginLeft(horizontalThumb, '0px', '0px');
}, 625);
} else {
verticalThumb.style.top = `${verticalRatio * (containerHeight - verticalThumbHeight)}px`;
horizontalThumb.style.left = `${horizontalRatio * (containerWidth - horizontalThumbWidth)}px`;
}
}
function scrollContent() {
const containerHeight = container.clientHeight;
const contentHeight = content.scrollHeight;
const containerWidth = container.clientWidth;
const contentWidth = content.scrollWidth;
const verticalThumbHeight = verticalThumb.clientHeight;
const horizontalThumbWidth = horizontalThumb.clientWidth;
const verticalRatio = verticalThumb.offsetTop / (containerHeight - verticalThumbHeight);
const horizontalRatio = horizontalThumb.offsetLeft / (containerWidth - horizontalThumbWidth);
content.scrollTop = verticalRatio * (contentHeight - containerHeight);
content.scrollLeft = horizontalRatio * (contentWidth - containerWidth);
}
verticalThumb.addEventListener('mousedown', function(e) {
e.preventDefault();
const startY = e.clientY;
const startTop = verticalThumb.offsetTop;
function onMouseMove(e) {
const deltaY = e.clientY - startY;
const newTop = Math.min(Math.max(startTop + deltaY, 18), container.clientHeight - verticalThumb.clientHeight - 18);
verticalThumb.style.top = `${newTop}px`;
scrollContent();
}
function onMouseUp() {
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
}
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
});
horizontalThumb.addEventListener('mousedown', function(e) {
e.preventDefault();
const startX = e.clientX;
const startLeft = horizontalThumb.offsetLeft;
function onMouseMove(e) {
const deltaX = e.clientX - startX;
const newLeft = Math.min(Math.max(startLeft + deltaX, 18), container.clientWidth - horizontalThumb.clientWidth - 18);
horizontalThumb.style.left = `${newLeft}px`;
scrollContent();
}
function onMouseUp() {
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
}
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
});
content.addEventListener('scroll', updateScrollbars);
window.addEventListener('resize', updateScrollbars);
updateScrollbars();
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment